Setup Docker inside Proxmox
Alpine Linux Docker VM on Proxmox
A lightweight Docker host that just works.
Alpine is tiny, fast, maintained, and honestly a better long-term choice.
bash
.hddddddddddddddddddddddh. root@docker01
:dddddddddddddddddddddddddd: -------------
/dddddddddddddddddddddddddddd/ OS: Alpine Linux v3.24 x86_64
+dddddddddddddddddddddddddddddd+ Host: KVM/QEMU Standard PC
`sdddddddddddddddddddddddddddddddds` Kernel: Linux 6.18.38-0-lts
`ydddddddddddd++hdddddddddddddddddddy` Uptime: 7 mins
.hddddddddddd+` `+ddddh:-sdddddddddddh. Packages: 131 (apk)
hdddddddddd+` `+y: .sddddddddddh Shell: sh
ddddddddh+` `//` `.` -sddddddddd Display (Virtual-1): 1024x768, 60 Hz
ddddddh+` `/hddh/` `:s- -sddddddd Terminal: /dev/pts/0
ddddh+` `/+/dddddh/` `+s- -sddddd CPU: QEMU Virtual version 2.5+ (2) @ 3.59 GHz
ddd+` `/o` :dddddddh/` `oy- .yddd GPU: Red Hat, Inc. QXL paravirtual graphic card
hdddyo+ohddyosdddddddddho+oydddy++ohdddh Memory: 481.02 MiB / 5.79 GiB (8%)
.hddddddddddddddddddddddddddddddddddddh. Swap: 0 B / 4.00 GiB (0%)
`yddddddddddddddddddddddddddddddddddy` Disk (/): 1.23 GiB / 132.52 GiB (1%) - ext4
`sdddddddddddddddddddddddddddddddds` Local IP (eth0): 192.168.0.226/24
+dddddddddddddddddddddddddddddd+ Locale: C.UTF-8
/dddddddddddddddddddddddddddd/
:dddddddddddddddddddddddddd:
.hddddddddddddddddddddddh. Why Alpine?
| Alpine | Ubuntu |
|---|---|
| 200MB install | Several GB |
| Fast boot | Slower |
| Very low RAM usage | Higher RAM usage |
| Minimal attack surface | Lots of unnecessary packages |
| Perfect for Docker | General-purpose OS |
Requirements
Before starting:
- Proxmox VE installed
- Alpine Linux ISO downloaded
- Internet access
- VirtIO drivers (default in Proxmox)
- IQ higher than 78
VM Configuration
| Setting | Value |
|---|---|
| Machine | q35 |
| BIOS | SeaBIOS |
| CPU Type | host |
| CPU | 2-4 Cores |
| RAM | 2-4 GB |
| Disk | 32GB minimum (50GB recommended) |
| Disk Bus | VirtIO SCSI |
| Network | VirtIO |
| Bridge | vmbr0 |
Enable:
- SSD Emulation
- Discard
- QEMU Guest Agent
Installation
Boot the Alpine ISO.
Login as
rootNo password.
Run
bash
setup-alpineRecommended Answers
| Question | Answer |
|---|---|
| Keyboard | us |
| Hostname | docker01 |
| Network | eth0 |
| IP | dhcp |
| Root Password | Strong Password |
| Timezone | Your Timezone |
| Mirror | Fastest |
| SSH | openssh |
| Disk | sda |
| Install | sys |
After installation shutdown:
bash
poweroffRemove the ISO from Hardware options.
Boot again.
Update Everything
bash
apk update
apk upgradeInstall Packages
bash
apk add \
docker \
docker-cli-compose \
qemu-guest-agent \
openssh \
bash \
curl \
wget \
git \
nano \
vim \
htop \
iftop \
bind-tools \
iproute2 \
ca-certificatesEnable Services
Docker:
bash
rc-update add docker boot
service docker startSSH:
bash
rc-update add sshd
service sshd startGuest Agent:
bash
rc-update add qemu-guest-agent
service qemu-guest-agent startVerify
bash
docker version
docker compose version
service docker status
service sshd status
service qemu-guest-agent statusTest Docker
bash
docker run hello-worldIf this works, you're done with the OS.
Everything else is just containers.
Directory Structure
We will keep everything inside /opt/docker
/opt/docker
│
├── compose/
│ ├── portainer/
│ ├── nginx-proxy-manager/
│ ├── forgejo/
│ ├── ghost/
│ ├── navidrome/
│ └── ...
│
├── data/
│
├── backups/
│
└── scripts/Create it:
bash
mkdir -p /opt/docker/{compose,data,backups,scripts}Portainer
/opt/docker/compose/portainerdocker-compose.yml:
yaml
services:
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
restart: unless-stopped
ports:
- "9000:9000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
volumes:
portainer_data:Start:
bash
docker compose up -dOpen this in browser:
http://ALPINE_SERVER_IP:9000Useful Commands
Network
Get IP Address:
bash
ip addrGet Gateway:
bash
ip routeDNS Test:
bash
ping google.comCheck Internet:
bash
ping 1.1.1.1Test HTTPS Request:
bash
curl https://google.comSystem
Memory:
bash
free -hDisk:
bash
df -hProcesses:
bash
topServices:
bash
rc-statusBoot Services:
bash
rc-update showDocker
Containers:
bash
docker ps
docker ps -aImages:
bash
docker imagesVolumes:
bash
docker volume lsNetworks:
bash
docker network lsLogs:
bash
docker logs CONTAINERShell:
bash
docker exec -it CONTAINER shRestart:
bash
docker restart CONTAINERCompose
Start:
bash
docker compose up -dStop:
bash
docker compose downRestart:
bash
docker compose restartLogs:
bash
docker compose logs -fUpdate:
bash
docker compose pull
docker compose up -dDNS
Temporary:
bash
nano /etc/resolv.confExample:
nameserver 1.1.1.1
nameserver 8.8.8.8For Iran:
nameserver 178.22.122.100
nameserver 185.51.200.2Troubleshooting
APK won't install packages
bash
cat /etc/alpine-release
cat /etc/apk/repositories
apk updateDocker won't start
bash
service docker status
bash
service docker restartDocker Hub timeout
Check:
bash
ping 1.1.1.1
ping google.com
curl https://auth.docker.io
docker run hello-worldMost of the time it isn't Docker.
It's either:
- DNS
- Packet loss
- ISP filtering
- Bad routing
Final Layout
flowchart TD
P[Proxmox]
P --> VM
subgraph VM["Alpine Docker VM"]
Docker
SSH
QGA["QEMU Guest Agent"]
Docker --> Compose
Compose --> Portainer
Compose --> NPM["Nginx Proxy Manager"]
Compose --> Forgejo
Compose --> Ghost
Compose --> Navidrome
Compose --> More["More Services..."]
end
Filesystem
graph TD root["/"] root --> opt opt --> docker docker --> compose docker --> data docker --> backups docker --> scripts compose --> portainer compose --> forgejo compose --> ghost compose --> navidrome compose --> nginx compose --> more